/**
 * 
 */
package com.sep.team4;

import java.util.ArrayList;
import java.util.Map;

import android.net.Uri;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.sep.team4.data.Course;
import com.sep.team4.data.CourseData;
import com.sep.team4.data.CourseItem;
import com.sep.team4.data.DatabaseManager;
import com.sep.team4.data.Grade;
import com.sep.team4.data.StudyData;
import com.sep.team4.data.StudyItem;
import com.sep.team4.data.Test;

/**
 * @author Erik
 * 
 */
public class JsonHandler {

	private static JsonHandler instance = null;
	Uri uri;

	public JsonHandler(Uri uri) {
		this.uri = uri;
		getRestData();
	}

	public static JsonHandler getInstance(Uri uri) {
		if (instance == null) {
			instance = new JsonHandler(uri);
		}
		return instance;
	}

	public void getRestData() {
		DatabaseManager db = DatabaseManager.getInstance();
		String message = invoke("https://rest.hz.nl/api/json/StudieResultaten",
				new ArrayList<Map.Entry<String, String>>());
		Log.e("tagg", message);
		JsonElement json = new JsonParser().parse(message);
		Gson gson = new Gson();
		StudyData data = gson.fromJson(json, StudyData.class);
		message = invoke("https://rest.hz.nl/api/json/Courses",
				new ArrayList<Map.Entry<String, String>>());
		json = new JsonParser().parse(message);
		CourseData courses = gson.fromJson(json, CourseData.class);
		for (CourseItem item : courses.getItems()) {
			Course c = new Course();
			c.setSBU(Integer.parseInt(item.getMaxSBU()));
			c.setName(item.getCourseName());
			c.setCourseID(db.getNextAvailableCourseID());
			c.setCode(item.getCourseCode());
			for (StudyItem i : data.getItems()) {
				if (i.getCourseName().equals(c.getName())) {
					String[] sem;
					String semester;
					if(i.getTimeperiod().contains("-")){
						sem = i.getTimeperiod().split("-");
						semester = sem[1] + " - " + sem[0];
					}else{
						semester = i.getTimeperiod();
					}
					
					c.setSemester(semester.trim());
					if (db.getCourseByName(c.getName()) == null) {
						db.addCourse(c);
					}
					Test test = new Test();
					test.setLowestAllowedGrade(Double.parseDouble(i
							.getBottomMark()));
					test.setName(i.getTestName());
					test.setWeight(Integer.parseInt(i.getWeight()));
					test.setTestID(db.getNextAvailableTestID());
					if (i.getAttempt().equals("1")) {
						db.addTest(test, c.getCourseID());
					}
					for (StudyItem s : data.getItems()) {
						if (s.getTestName().equals(test.getName())) {
							Grade grade = new Grade();
							try {
								grade.setValue(Double.parseDouble(i.getMark()));
								grade.setAttempt(Integer.parseInt(i
										.getAttempt()));
							} catch (Exception e) {
								grade.setValue(5.5);
								grade.setAttempt(5);
							}
							db.addGrade(grade, test.getTestID());
						}
					}
				}
			}

		}
		ArrayList<String> sem = db.getAttendedSemesters();
		for (String s : sem) {
			ArrayList<Course> c = db.getCoursesBySemester(s);
			for (Course cc : c) {
				Log.e("Course naam: ", cc.getName());
				Log.e("Course code : ", cc.getCode());
				Log.e("Course semester : ", cc.getSemester());
				Log.e("Course Ec's : ", new Double(cc.getSBU() / 28).toString());
				ArrayList<Test> tests = cc.getTests();
				for (Test t : tests) {
					Log.e("Toets naam: ", t.getName());
					Log.e("Toets bodumcijfer: ",
							new Double(t.getLowestAllowedGrade() / 10)
									.toString());
					Log.e("Toets gewicht: ",
							new Double(t.getWeight()).toString());
					ArrayList<Grade> grades = t.getGrades();
					for (Grade g : grades) {
						Log.e("Cijfer:", new Double(g.getValue()).toString());
						Log.e("Poging: ", new Double(g.getAttempt()).toString());
					}
				}
			}
		}

	}
	
	public void getUpdates(){
		//TODO
	}

	/**
	 * invoke Service from server
	 * 
	 * @param uri
	 *            service to be called
	 * @param params
	 *            extra parameters to be sent with call
	 * @return data received by call
	 */
	private String invoke(String uri,
			ArrayList<Map.Entry<String, String>> params) {
		OAuthHandler oAuthHandler = OAuthHandler.getInstance();
		oAuthHandler.getAccessToken(this.uri);
		return oAuthHandler.invoke(uri, params);
	}

}
